﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web.Mvc;
using Elmah;
using Viettel.VOFFICE.DAO.Models;
using Viettel.VOFFICE.Web.Helpers;
using Viettel.VOFFICE.Web.Models;
using Viettel.VOFFICE.util;

namespace Viettel.VOFFICE.Web.Controllers
{
    public class DepartmentController : BaseController
    {
        [HttpGet]
        [ActionName("get_one")]
        public JsonResult GetById(int id)
        {
            var dept = unitOfWork.DeparmentRepository.GetById(id);
            return Json(new JsonResponse()
                            {
                                Status = true,
                                Result = new DepartmentModel(dept)
                            },
                        JsonRequestBehavior.AllowGet
                );
        }

        [HttpGet]
        [ActionName("get_model")]
        public JsonResult GetHierarchicalModel()
        {
            var deptList =
             unitOfWork.DeparmentRepository.Get().Select(
                 o => new DepartmentModel { Id = o.Id, Name = o.Name, Description = o.Description, ParentId = o.ParentId }).
                 ToList();
            var rootDept = deptList.FirstOrDefault(s => s.ParentId == null);
            SetChildren(rootDept, deptList);
            return Json(
                new JsonResponse()
                    {
                        Status = true,
                        Result = rootDept
                    }, JsonRequestBehavior.AllowGet
                );
        }

        [HttpGet]
        [ActionName("get_list")]
        public JsonResult GetList(int? parentId, int pageIndex = 0, int pageSize = 0)
        {
            //có phân trang
            try
            {
                if (pageSize > 0 && pageIndex >= 0)
                {
                    var list = unitOfWork.DeparmentRepository
                        .GetWithPaging(parentId, pageIndex, pageSize);
                    return Json(new JsonResponse()
                    {

                        Status = true,
                        Result = new
                        {
                            PageIndex = list.PageIndex,
                            PageSize = list.PageSize,
                            PageCount = list.PageCount,
                            List = list.Select(o => new DepartmentModel(o))
                        }
                    }, JsonRequestBehavior.AllowGet);
                }
                //không phân trang
                else
                {

                    var list = unitOfWork.DeparmentRepository.Get().Select(o => new DepartmentModel(o));
                    return Json(new JsonResponse() { Status = true, Result = list }, JsonRequestBehavior.AllowGet);
                } //end if
            }
            catch (Exception ex)
            {
                ErrorSignal.FromCurrentContext().Raise(new NotSupportedException("", ex));
                return Json(SimplyResponse.Response500(), JsonRequestBehavior.AllowGet);
                throw;
            }//end try
        }

        [HttpPut]
        [ActionName("update_dept")]
        [ValidateJsonAntiForgeryToken(Salt = AppConstants.TokenSalt)]
        public JsonResult Update(DepartmentModel model, string modifiedscope = "all")
        {
            try
            {
                List<ValidationResult> outError;
                if (model.IsValid(out outError))
                {
                    var dbDept = unitOfWork.DeparmentRepository.GetById(model.Id);
                    if (dbDept == null)
                    {
                        return Json(new JsonResponse()
                        {
                            Status = false,
                            Result = Resources.Resources.ManageBookBookNotFound
                        });
                    }
                    if (modifiedscope.ToUpper().Contains("ISACTIVE"))
                    {
                        dbDept.IsActive = model.IsActive;
                    }
                    else//cập nhập hết
                    {
                        dbDept.Name = model.Name;
                        dbDept.Description = model.Description;
                        dbDept.OfficeCode = model.OfficeCode;
                        dbDept.IsActive = model.IsActive;
                    }//end if
                    dbDept.UpdatedAt = DateTime.Now;
                    unitOfWork.DeparmentRepository.Update(dbDept);
                    return Json(SimplyResponse.Response200());
                }
                else
                {
                    return Json(new JsonResponse()
                    {
                        Status = false,
                        Result = string.Join(", ", outError.Select(o => o.ErrorMessage).ToArray())
                    });
                }//end ìf
            }
            catch (Exception)
            {
                return Json(SimplyResponse.Response500());
                //throw;
            }
        }

        [HttpPost]
        [ActionName("add_dept")]
        [ValidateJsonAntiForgeryToken(Salt = AppConstants.TokenSalt)]
        public JsonResult AddDept(DepartmentModel model)
        {
            try
            {
                try
                {
                    List<ValidationResult> outError;
                    if (model.IsValid(out outError))
                    {
                        var dbDept = new v_Department
                        {
                            //Id = book.Id,
                            Name = model.Name,
                            Description = model.Description,
                            ParentId = model.ParentId,
                            Node = model.Node,
                            OfficeCode = model.OfficeCode,
                            IsActive = model.IsActive,
                            CreatedAt = DateTime.Now,
                            UpdatedAt = DateTime.Now
                        };
                        unitOfWork.DeparmentRepository.Insert(dbDept);
                        return Json(SimplyResponse.ResposeWithId(dbDept.Id));
                    }
                    else
                    {
                        return Json(new JsonResponse()
                        {
                            Status = false,
                            Result = string.Join(", ", outError.Select(o => o.ErrorMessage).ToArray())
                        });
                    }//end ìf
                }
                catch (Exception)
                {
                    return Json(SimplyResponse.Response500());
                    //throw;
                }
            }
            catch (Exception)
            {
                return Json(SimplyResponse.Response500());
                //throw;
            }
        }

        [HttpPost]
        [ActionName("get_department_tree")]
        public JsonResult GetDeptTreeData()
        {
            var rootDept = unitOfWork.DeparmentRepository.GetRootDepartment();

            if (rootDept != null)
            {
                var rootNode = new DeptTreeModel { attr = new DeptTreeAttr(), data = rootDept.Name };

                rootNode.attr.id = rootDept.Id;
                rootNode.attr.title = rootDept.Name;
                PopulateTree(rootDept.Id, rootNode);

                return Json(rootNode);
            }
            return Json(null);
        }

        [HttpPost]
        [ActionName("delete_department")]
        [ValidateJsonAntiForgeryToken(Salt = AppConstants.TokenSalt)]
        public JsonResult DeleteDepartment(int id)
        {
            var targetDept = unitOfWork.DeparmentRepository.GetById(id);
            if (targetDept != null)
            {
                unitOfWork.DeparmentRepository.Delete(id);
                return Json(SimplyResponse.Response200());
            }
            return Json(SimplyResponse.Response500(Resources.Resources.ManageDepartment_DataInUse));
        }

        [HttpGet]
        [ActionName("get_users")]
        public JsonResult GetUsers(int id)
        {
            var deptList = unitOfWork.UserRepository.Get();
            var uidList = unitOfWork.DeparmentRepository.GetUserInDepartmentById(id);
            var returnList = deptList.Select(item => new UidModel
                                                         {
                                                             DepartmentId = id,
                                                             UserName = item.UserName,
                                                             IsInDept = uidList != null && uidList.Select(s => s.UserId).Contains(item.UserId)
                                                         }).ToList();
            return Json(
                new JsonResponse()
                    {
                        Status = true,
                        Result = returnList
                    }
                , JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        [ActionName("assign_user")]
        [ValidateJsonAntiForgeryToken(Salt = AppConstants.TokenSalt)]
        public JsonResult AssignUser(UidModel model)
        {
            var firstOrDefault = unitOfWork.UserRepository.FindByName(model.UserName).FirstOrDefault();
            if (firstOrDefault != null)
            {
                if (model.IsInDept)
                {

                    var uidModel = new v_UsersInDepartment
                                       {
                                           DeparmentId = model.DepartmentId,
                                           UserId = firstOrDefault.UserId,
                                           CreatedAt = DateTime.Now,
                                           CreatorId = GetCurentUserId(),
                                           IsActive = true,
                                           UpdatedAt = DateTime.Now
                                       };
                    unitOfWork.DeparmentRepository.AddUserToDepartment(uidModel);

                }
                else
                {
                    unitOfWork.DeparmentRepository.RemoveUserInDepts(firstOrDefault.UserId, model.DepartmentId);
                }
                return Json(SimplyResponse.Response200());
            }
            return Json(SimplyResponse.Response500());
        }

        [HttpPost]
        [ActionName("move_department")]
        public JsonResult MoveDepartment(int curentid, int? parentid)
        {
            var curentDept = unitOfWork.DeparmentRepository.GetById(curentid);
            if (curentDept != null)
            {
                curentDept.ParentId = parentid;
                unitOfWork.DeparmentRepository.Update(curentDept);
                return Json(SimplyResponse.Response200());
            }
            return Json(SimplyResponse.Response500());
        }

        private void PopulateTree(int rootPath, DeptTreeModel rootNode)
        {
            if (rootNode.children == null)
            {
                rootNode.children = new List<DeptTreeModel>();
            }
            foreach (var item in unitOfWork.DeparmentRepository.GetDeptByParentId(rootPath))
            {
                var newRoot = new DeptTreeModel { attr = new DeptTreeAttr(), data = item.Name };
                newRoot.attr.id = item.Id;
                newRoot.attr.title = item.Name;
                PopulateTree(item.Id, newRoot);
                rootNode.children.Add(newRoot);
            }
        }

        #region Get Dept Treeview Data
        private void SetChildren(DepartmentModel deptModel, List<DepartmentModel> deptList)
        {
            var childs = deptList.Where(s => s.ParentId == deptModel.Id).ToList();
            if (!childs.Any()) return;
            foreach (var child in childs)
            {
                SetChildren(child, deptList);
                deptModel.SubDepts.Add(child);
            }
        }
        #endregion
    }
}
